---
sidebar_label: Use serverless functions
sidebar_position: 5
description: Use serverless functions with Hasura Event Triggers
keywords:
  - hasura
  - docs
  - event trigger
  - serverless function
---

# Use Serverless Functions

## Introduction

You can use serverless functions along with Event Triggers to design an
async business workflow without having to manage any dedicated
infrastructure.

As Hasura Event Triggers can deliver database events to any webhook,
serverless functions can be perfect candidates for their handlers.

## Why use serverless functions?

1.  Cost effectiveness.
2.  No infra management.
3.  Async business logic.

## Examples

You can find a bunch of examples for various serverless cloud providers
in this repo:

<https://github.com/hasura/graphql-engine/tree/master/community/boilerplates/event-triggers>.

### For example: update related data on a database event

In this example we make a note taking app. Whenever a user updates their
note, we want to store a revision of that note in a separate table.

You can find the complete example at:

<https://github.com/hasura/graphql-engine/tree/master/community/boilerplates/event-triggers/aws-lambda/nodejs6/mutation>.

Let's consider the following simplified schema for the above:

```sql
notes (
  id INT PRIMARY KEY,
  note TEXT
)

note_revision (
  id INT PRIMARY KEY,
  note TEXT,
  note_id INT FOREIGN KEY REFERENCES notes(id),
  update_at TIMESTAMP DEFAULT now()
)
```

Whenever an update happens to the `notes` table, we want to insert a row
into the `note_revision` table.

For this we [set up an Event Trigger](/event-triggers/create-trigger.mdx) on `UPDATE` to the
`notes` table which calls an AWS Lambda function. The AWS Lambda
function itself uses a GraphQL mutation to insert a new row into the
`note_revision` table. As the [Event Trigger payload](/event-triggers/payload.mdx) in case of updates gives us both the old and the new data, we can store
the old note data in our revision table.

Our AWS Lambda code looks like this:

```javascript
// Lambda which gets triggered on insert, and in turns performs a mutation

const fetch = require('node-fetch');

const adminSecret = process.env.ADMIN_SECRET;
const hgeEndpoint = process.env.HGE_ENDPOINT;

const query = `
  mutation updateNoteRevision ($noteId: Int!, $data: String!) {
    insert_note_revision (objects: [
      {
        note_id: $noteId,
        note: $data
      }
    ]) {
      affected_rows
    }
  }
`;

exports.handler = (event, context, callback) => {
  let request;
  try {
    request = JSON.parse(event.body);
  } catch (e) {
    return callback(null, { statusCode: 400, body: 'cannot parse hasura event' });
  }

  const response = {
    statusCode: 200,
    body: 'success',
  };
  const qv = { noteId: request.event.data.old.id, data: request.event.data.old.note };
  fetch(hgeEndpoint + '/v1/graphql', {
    method: 'POST',
    body: JSON.stringify({ query: query, variables: qv }),
    headers: { 'Content-Type': 'application/json', 'x-hasura-admin-secret': adminSecret },
  })
    .then(res => res.json())
    .then(json => {
      console.log(json);
      callback(null, response);
    });
};
```
